package com.dinzeer.legendreliclib.lib.util.dash;

import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkEvent;

import java.util.function.Supplier;

/**
 * 用于网络传输的冲刺消息类，包含垂直速度分量和冲刺距离参数。
 * <p>
 * 该类实现了从字节缓冲区编码/解码消息的方法，并处理网络事件。
 */
public class DashMessage {
    /**
     * 垂直方向的速度分量。
     */
    final double dy;

    /**
     * 水平冲刺距离。
     */
    final double dashDistance;

    /**
     * 构造冲刺消息。
     *
     * @param dy          垂直方向的速度分量
     * @param dashDistance 水平冲刺距离
     */
    public DashMessage(double dy, double dashDistance) {
        this.dy = dy;
        this.dashDistance = dashDistance;
    }

    /**
     * 将消息编码到字节缓冲区。
     *
     * @param msg    要编码的消息对象
     * @param buffer 目标字节缓冲区
     */
    public static void encode(DashMessage msg, FriendlyByteBuf buffer) {
        buffer.writeDouble(msg.dy);
        buffer.writeDouble(msg.dashDistance);
    }

    /**
     * 处理接收到的网络消息。
     *
     * @param msg 接收到的消息对象
     * @param ctx 网络事件上下文
     */
    public static void handle(DashMessage msg, Supplier<NetworkEvent.Context> ctx) {
        ctx.get().enqueueWork(() -> ClientPacketHandler.handledash(msg));
        ctx.get().setPacketHandled(true);
    }

    /**
     * 从字节缓冲区解码消息。
     *
     * @param buffer 源字节缓冲区
     * @return 解码后的消息对象
     */
    public static DashMessage decode(FriendlyByteBuf buffer) {
        return new DashMessage(buffer.readDouble(), buffer.readDouble());
    }

    /**
     * 根据实体的当前朝向计算并设置移动向量。
     * <p>
     * 该方法会计算水平面内基于实体朝向的分量，并应用垂直速度分量，最终设置实体的运动向量。
     *
     * @param livingEntity 要移动的实体
     * @param dy           垂直方向的速度分量
     * @param dashDistance 水平冲刺距离
     */
    public static void vmove(LivingEntity livingEntity, double dy, double dashDistance) {
        float yaw = livingEntity.getYRot();
        double dx = -Math.sin(Math.toRadians(yaw)) * dashDistance;
        double dz = Math.cos(Math.toRadians(yaw)) * dashDistance;
        livingEntity.setDeltaMovement(new Vec3(dx, dy, dz));
    }
}